/*
 * =====================================================================================
 *
 *       Filename:  bitmap.c
 *
 *    Description:  使用位图来标记哪个端口号是否被占用
 *
 *        Version:  1.0
 *        Created:  2019年02月19日 14时07分28秒
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  YOUR NAME (), 
 *   Organization:  
 *
 * =====================================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>



/*
 * bitmap计算示例
 *   port_start = 40000;
 *   port_end   = 45000;
 *   array_size = (port_end - port_start + 1)
 *
 *   给定一个端口port
 *   port_offset = port - port_start + 1
 *   index = port_offset/(8 * sizeof(char))
 *   bit_offset = port_offset%(8 * sizeof(char))
 *
 *   测试此位是否被占用
 *   test = (char)(1 << bit_offset);
 *   if(bitmap[index] & (1 << bit_offset)) 
 */


/* 3200 */
char bitmap[400] = {0};
unsigned short port_base = 40000;

enum bitoff {
    BIT_OFFSET_0 = 0,
    BIT_OFFSET_1,
    BIT_OFFSET_2,
    BIT_OFFSET_3,
    BIT_OFFSET_4,
    BIT_OFFSET_5,
    BIT_OFFSET_6,
    BIT_OFFSET_7,
};

int test_bit(char num, enum bitoff offset)
{
    return (num & (char)(1 << offset));
}

void set_bit(char *num, enum bitoff offset)
{
    *num = *num | (char)(1 << offset);
}

void clear_bit(char *num, enum bitoff offset)
{
    *num = *num & (~(char)(1 << offset));
}


int test_port(unsigned short port)
{
    unsigned offset = port - port_base;
    int index = offset/(8 * sizeof(char));
    int bit_offset = offset%(8 * sizeof(char));

    printf("port = %d, index = %d, bit_offset = %d\n", port, index, bit_offset);
    if(test_bit(bitmap[index], bit_offset)) {
        printf("Bit is set\n");
    }
    else {
        printf("Bit is not set\n");
    }
    return 0;
}


void set_port(unsigned short port)
{
    unsigned offset = port - port_base;
    int index = offset/(8 * sizeof(char));
    int bit_offset = offset%(8 * sizeof(char));

    set_bit(&bitmap[index], bit_offset);
}

void clear_port(unsigned short port)
{
    unsigned offset = port - port_base;
    int index = offset/(8 * sizeof(char));
    int bit_offset = offset%(8 * sizeof(char));

    clear_bit(&bitmap[index], bit_offset);
}


int main(int argc, char **argv)
{
    int i = 0;
    for(i = 40000; i <= 40063; i++) {
        set_port(i);
        test_port(i);
        clear_port(i);
        test_port(i);
        printf("\n");
    }
    return 0;
}


